package com.zdp.filesync.rsync.handle;

import com.zdp.filesync.commonline.service.CommonLine;
import com.zdp.filesync.monitor.config.FileMonitorConfig;
import com.zdp.filesync.monitor.config.FileMonitorInfo;
import com.zdp.filesync.rsync.config.RsyncConfig;
import com.zdp.filesync.rsync.config.RsyncServerConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.List;

/**
 * Rsync的操作类
 * 删除配置，新增配置，修改配置
 * 重启应用
 */
@Component
@Slf4j
public class RsyncHandle implements InitializingBean {

    @Autowired
    private CommonLine commonLine;

    @Autowired
    private RsyncServerConfig rsyncServerConfig;

    @Autowired
    private FileMonitorConfig fileMonitorConfig;

    private int count = 20;
    /**
     * 重启 rsync应用
     */
    public void restart(){
        // 先关闭，再启动
        String s = commonLine.execOrigin(rsyncServerConfig.buildStopBash());
        log.info("关闭rsync服务，返回结果:{}",s);
        // 启动应用 -- > 启动这边要保证 rsync服务成功启动
        // todo 后续可以添加一个 重试的工具类
        start();
    }

    private void start(){
        int i = 0;
        do {
            i++;
            try {
                Thread.sleep(1000);
                // 启动服务时需要先删除pid文件
                commonLine.execOrigin(rsyncServerConfig.buildDelPidFileBash());
                commonLine.execOrigin(rsyncServerConfig.buildStartBash());
            } catch (InterruptedException e) {
                log.warn("启动线程睡眠被打断,继续进行启动操作",e);
                commonLine.execOrigin(rsyncServerConfig.buildStartBash());
            }
        }while (!commonLine.execHandleResult(rsyncServerConfig.buildIsExistRsyncServerBash(),
                line -> {
                    line = line.replaceAll(" ", "");
                    String startBash = rsyncServerConfig.buildStartBash();
                    startBash = startBash.replaceAll(" ","");
                    return StringUtils.isNoneBlank(line) && line.contains(startBash);
                }) && i<count);
        if(i>=count){
            log.warn("启动失败，请手动启动 rsync 服务，启动命令: {}",rsyncServerConfig.buildStartBash());
        }else{
            log.info("rsync 服务启动成功");
        }
    }

    /**
     * 删除 rsync配置中的 model配置信息
     * @param fileMonitorInfos 需要删除的model
     */
    public void delModelConfig(List<FileMonitorInfo> fileMonitorInfos){
        if(CollectionUtils.isEmpty(fileMonitorInfos)){
            log.info("没有需要删除的rsync 模块信息");
            return ;
        }
        fileMonitorInfos.forEach(fileMonitorInfo -> {
            RsyncConfig config = RsyncConfig.buildRsyncConfig(rsyncServerConfig,fileMonitorInfo);
            commonLine.execOrigin(config.buildDelConfigBash());
        });

    }

    /**
     * 新增 rsync 的模块配置
     * @param fileMonitorInfos
     */
    public void addModelConfig(List<FileMonitorInfo> fileMonitorInfos){
        if(CollectionUtils.isEmpty(fileMonitorInfos)){
            log.info("没有需要添加的 rsync 模块信息");
            return ;
        }
        fileMonitorInfos.forEach(fileMonitorInfo -> {
            RsyncConfig config = RsyncConfig.buildRsyncConfig(rsyncServerConfig,fileMonitorInfo);
            commonLine.execOrigin(config.buildAddConfigBash());
        });
    }


    /**
     * 初始化 rsync服务端配置，并启动rsync服务
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        initConfigBefore();
        // 应用启动时，需要去启动一个 rsync 服务
        // 重新生成配置文件
        // 构建公共配置
        String buildRes = commonLine.execOrigin(rsyncServerConfig.buildInitConfigBash());
        log.info("执行构建公共配置文件命令，返回结果:{}",buildRes);
        // 构建 model信息
        List<FileMonitorInfo> fileMonitorInfos = fileMonitorConfig.getFileMonitorInfos();
        if(!CollectionUtils.isEmpty(fileMonitorInfos)){
            fileMonitorInfos.forEach(fileMonitorInfo -> {
                RsyncConfig rsyncConfig = RsyncConfig.buildRsyncConfig(rsyncServerConfig,fileMonitorInfo);
                commonLine.execOrigin(rsyncConfig.buildAddConfigBash());
            });
        }
        // 启动 rsync服务
        restart();
    }

    /**
     * 初始化配置文件时的操作，先删除一些相关的东西
     */
    private void initConfigBefore(){
        // 删除配置文件
        String res = commonLine.execOrigin(rsyncServerConfig.buildDelConfigBash());
        log.info("执行删除配置文件命令，返回结果:{}",res);

        res = commonLine.execOrigin(rsyncServerConfig.buildDelPwdBash());
        log.info("执行删除 rsync 密码文件，返回结果:{}",res);

        String addRes = commonLine.execOrigin(rsyncServerConfig.buildAddPwdBash());
        log.info("执行写入密码文件操作，返回结果:{}",addRes);
        // 修改密码文件权限
        String chmodRes = commonLine.execOrigin(rsyncServerConfig.buildChmodPwdFileBash());
        log.info("执行修改密码文件权限操作，返回结果:{}",chmodRes);
    }
}
